import {
  UserApplyState, UserOnOffLineState,
  WebSocketNewMessage,
  WebSocketReqMsgContentType,
  WebSocketResponseMessageType,
} from '/@/utils/types'

import { global } from '/@/config/global'
import { useUserStore, useWebSocketStore, useUserFriendStore } from '/@/store'
import { ElNotification } from 'element-plus'
import { UserApplyCriteria } from '/@/api/openapi'

// 定义一个 子线程用来传递 websocket 事件
const worker: Worker = new Worker(new URL('./worker.ts', import.meta.url), {
  type: 'module',
})

class WebSocketUtils {
  // 定义需要发送消息的列表。相当于队列
  #tasks: WebSocketReqMsgContentType[] = []

  // 连接是否已经建立
  #connectReady: boolean = false

  // 定义 构造函数。初始化WebSocket
  constructor() {
    console.log('WebSocketUtils 构造函数')
    // 进行初始化
    this.initConnect()
    // 收到消息的 worker线程，传递到 websocke.ts 线程。调用 workermsg
    worker.addEventListener('message', this.onWorkerMsg)
  }

  // 定义初始化方法
  initConnect = () => {
    const token = localStorage.getItem(global.USER)
    console.log('websocket(step-01):初始化链接' + token)
    if (token) {
      console.log('websocket-initConnect--发送连接请求')
      // 发送消息给子线程 worker.ts 调用 initWS方法。参数是
      worker.postMessage(
        `{"type":"initWS","value":${token ? `"${token}"` : null}}`,
      )
    }
  }

  // 重置一些属性
  #onClose = () => {
    this.#connectReady = false
  }

  #send(msg: WebSocketReqMsgContentType) {
    worker.postMessage(
      `{"type":"message","value":${
        typeof msg === 'string' ? msg : JSON.stringify(msg)
      }}`,
    )
  }

  send = (params: WebSocketReqMsgContentType) => {
    if (this.#connectReady) {
      this.#send(params)
    } else {
      // 放到队列
      this.#tasks.push(params)
    }
  }

  onWorkerMsg = (e: MessageEvent<any>) => {
    // console.log(e)
    if (e === undefined) {
      return
    }
    const params: { type: string; value: unknown } = JSON.parse(e.data)
    switch (params.type) {
      case 'message': {
        this.onMessage(params.value as string)
        break
      }
      case 'open': {
        this.#dealTasks()
        break
      }
      case 'close':
      case 'error': {
        this.#onClose()
        break
      }
    }
  }

  #dealTasks = () => {
    // 连接已经建立成功了
    this.#connectReady = true
    // 先探测登录态
    // this.#detectionLoginStatus()

    setTimeout(() => {
      const user = useUserStore()
      // 如果登录成功的话。token信息不会成功
      if (user.isSign) {
        // 处理堆积的任务
        this.#tasks.forEach(task => {
          this.send(task)
        })
        // 清空缓存的消息
        this.#tasks = []
      } else {
        // 如果没登录，而且已经请求了登录二维码，就要更新登录二维码。
        // loginStore.loginQrCode && loginStore.getLoginQrCode()
      }
    }, 500)
  }

  onMessage = (value: string) => {
    const user = useUserStore()
    const userFriendStore = useUserFriendStore()
    const params: { type: WebSocketResponseMessageType; data: unknown } =
      JSON.parse(value)
    console.log(params)
    const webSocketStore = useWebSocketStore()

    switch (params.type) {
      case WebSocketResponseMessageType.OnOffLine:{
        console.log("用户上下线操作");
        const data = params.data as UserOnOffLineState
        console.log(params.data)
        console.log(data)
        
        // 更新群组在线人数
        if (webSocketStore.currentGroup) {
          webSocketStore.currentGroup.onlineNum = data.onlineNum
        }
        
        // 更新群组成员状态
        if (webSocketStore.currentGroupMember) {
          data.changeList.forEach(change => {
            const member = webSocketStore.currentGroupMember?.find(m => m.uid === change.uid)
            if (member) {
              member.activeStatus = change.activeStatus
            }
          })
        }
        break
      }
      // 接受到新的好友信息
      case WebSocketResponseMessageType.RequestNewFriend: {
        const data = params.data as UserApplyState
        userFriendStore.updateUserApplyMessage(data)
        // 重新申请信息
        const searchParams: UserApplyCriteria = {
          pageNum: 1,
          pageSize: 10,
        }
        userFriendStore.updateUserApply(searchParams)
        ElNotification({
          title: '新的好友申请',
          message: h(
            'i',
            { style: 'color: teal' },
            '申请者id:' + data.uid + '未读消息总数：' + data.unreadCount,
          ),
        })
        break
      }

      case WebSocketResponseMessageType.WSMsgRecall: {
        break
      }
      // 收到新消息
      case WebSocketResponseMessageType.ReceiveMessage: {
        const data = params.data as WebSocketNewMessage
        // 开始更新 新消息
        webSocketStore.updateNewMessage(data)
        break
      }

      case WebSocketResponseMessageType.NewFriendSession: {
        // 通过了好友申请。开始更新
        break
      }
    }
  }
}

export default new WebSocketUtils()
